package edu.fub.pub2search.app;

import java.sql.Time;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import edu.fub.pub2search.app.util.AndroidIOUtil;
import edu.fub.pub2search.app.util.JSONUtil;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Spinner;


/**
 * Activity for handling user's preference on the pubs, applying them
 * and storing them in SavedPreference.
 * 
 * @author Andrej
 */
public class Preference extends Activity {
	
	/** Variables for inputs */
	private CheckBox beerCheckBox;
	private CheckBox danceCheckBox;
	private CheckBox nosmokingCheckBox;
	private CheckBox livemusicCheckBox;
	private Spinner sHour;
	private Spinner sMin;
	
	@Override
    public void onCreate(Bundle icicle) {
       super.onCreate(icicle);
       
       setContentView(R.layout.preference);
       
       // Drop-down menu for preferred hour
       sHour = (Spinner) findViewById(R.id.spinner_hour);
       ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
               this, R.array.hours, android.R.layout.simple_spinner_item);
       adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
       sHour.setAdapter(adapter);
       
       // Drop-down menu for preferred minute
       sMin = (Spinner) findViewById(R.id.spinner_min);
       adapter = ArrayAdapter.createFromResource(this, R.array.minutes,
               android.R.layout.simple_spinner_item);
       adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
       sMin.setAdapter(adapter);
       
       // CheckBoxes of preferences
       beerCheckBox = (CheckBox) findViewById(R.id.beer_checkBox);
       danceCheckBox = (CheckBox) findViewById(R.id.dance_checkBox);
       nosmokingCheckBox = (CheckBox) findViewById(R.id.nosmoking_checkBox);
       livemusicCheckBox = (CheckBox) findViewById(R.id.livemusic_checkBox);
       
       // Load previous preference
       loadPreference();
       
       // Method invoke by click on APPLY button    
       Button applyButton = (Button) findViewById(R.id.apply_preference);
       applyButton.setOnClickListener(new OnClickListener(){
    		public void onClick(View v) {
    			// Revert applied preferences
    			revertPreference();
    			// Apply user's preferences
    	        applyPreference();    	        
    	        // Set result code for parent activity
    	        setResult(RESULT_OK);
    	        finish();        
    	    }
       });
       
       // Method invoke by click on REVERT button
       Button revertButton = (Button) findViewById(R.id.revert_preference);
       revertButton.setOnClickListener(new OnClickListener(){
    	   public void onClick(View v) {
    		   // Revert applied preferences
    		   revertPreference();
    		   // Reset preference to default
    		   resetPreference();
    		   // Load new reseted preferences into input checkboxes
    		   loadPreference();
    		   // Set result code for parent activity
    		   setResult(RESULT_OK);
    		   finish();
    	   }
       });
       
	}
	
	
// ------------------- PRIVATE METHODS ----------------------------	

	/*
	 * Method invoke by REVERT button,
	 * revert previously selected preferences
	 * and reset preference into default values   
	 */
	private void revertPreference() {
				
		String pubString = AndroidIOUtil.readDataFromFile("pub.txt", this);
		List<Map<String, String>> pubList = JSONUtil.getListFromJsonString(pubString);
		
		// Save new pub list in SingleCache
		SingleCache.getInstance().setCacheContent(pubList);
	}

	/*
	 *	Method invoked by APPLY button,
	 *	save user's preferences 
	 */
	private void applyPreference() {
		// Save user's preferences
		storePreference();
		
		// Load pubList and save as newPubList
		List<Map<String, String>> newPubList =
			SingleCache.getInstance().getCacheContent();
		
		// Create new pubList
		ArrayList<Map<String, String>> pubList =
			new ArrayList<Map<String, String>>();

		// Copy item from newPubList to pubList
		Iterator<Map<String, String>> iterNew = 		
			newPubList.iterator();
		while(iterNew.hasNext()){
			pubList.add(iterNew.next());
		}
		
		// Clean newPubList for later storage of new seelction of pubs
		newPubList.clear();
		
		// Retrieve preference options
		String minute = sMin.getSelectedItem().toString();
		String hour = sHour.getSelectedItem().toString();
		Time preferenceTime = Time.valueOf(hour+":"+minute+":00");
		
		// Loop in pubList
		Iterator<Map<String, String>> iter = 		
			pubList.iterator();
		while(iter.hasNext()){
			HashMap<String, String> pub = (HashMap<String, String>) iter.next();
			
			// Extracting time preference from DB, close_hour in format 00:00
			String closeHour = pub.get("close_hour").equals("00")? "24" : pub.get("close_hour");
			Time closeTime = Time.valueOf(closeHour+":00");
			// Extracting facility preference from DB (beer ...)
			String facility = pub.get("facility");
			
			// 
			if( isSatisfiedTime(preferenceTime, closeTime) && (
						isSatisfiedBeer("beer",facility) &&
						isSatisfiedDance("dance floor",facility) &&
						isSatisfiedLivemusic("live music", facility) &&
						isSatisfiedNosmoking("no smoking", facility)
				)
			) newPubList.add(pub);
				
		}
		
		// Save new content about the pubs in single cache
		SingleCache.getInstance().setCacheContent(newPubList);

	}
	
	
	/*
	 * Function to check whether the pub has no smoking facility
	 * 
	 * @param string input name of facility
	 * @param facility string of particular pub's facilities
	 * @return true if pub has facility, otherwise false
	 */
	private boolean isSatisfiedNosmoking(String string, String facility) {
		if(!(nosmokingCheckBox.isChecked())) return true;
		if (facility.toLowerCase().contains(string))
			return true;
		return false;
	}

	/*
	 * Function to check whether the pub has live music facility
	 * 
	 * @param string input name of facility
	 * @param facility string of particular pub's facilities
	 * @return true if pub has facility, otherwise false
	 */
	private boolean isSatisfiedLivemusic(String string, String facility) {
		if(!(livemusicCheckBox.isChecked())) return true;
		if (facility.toLowerCase().contains(string))
			return true;
		return false;
	}

	
	/*
	 * Function to check whether the pub has dance floor facility
	 * 
	 * @param string input name of facility
	 * @param facility string of particular pub's facilities
	 * @return true if pub has facility, otherwise false
	 */
	private boolean isSatisfiedDance(String string, String facility) {
		if(!(danceCheckBox.isChecked())) return true;
		if (facility.toLowerCase().contains(string))
			return true;
		return false;
	}

	/*
	 * Function to check whether the pub offer beer facility
	 * 
	 * @param string input name of facility
	 * @param facility string of particular pub's facilities
	 * @return true if pub has facility, otherwise false
	 */
	private boolean isSatisfiedBeer(String string, String facility){
		// If not checked, this preference evaluated as true
		if(!(beerCheckBox.isChecked())) return true;
		
		// If checked, then evaluate whether it is satisfied 
		if (facility.toLowerCase().contains(string))
			return true;
		return false;	
	}
	
	
	/*
	 * Function for compare two times and
	 * check whether pub satisfy time preference.
	 * 
	 * @param preferenceTime
	 * @param closeTime
	 * @return true if preferenceTime =< closeTime, otherwise false
	 */
	private boolean isSatisfiedTime(Time preferenceTime_, Time closeTime){
	
		// set a begining of day at 10:00
		Time timeStart = Time.valueOf("10:00:00");
		
		// create a copy of preferenceTime to purpose of shifting
		Time preferenceTime = (Time) preferenceTime_.clone();
		
		// shift a time (e.g. 10:00 become 00:00)
		int difference = (preferenceTime.getHours()-timeStart.getHours());
		if( difference < 0) difference += 24;
				
		Log.i("time_pref", preferenceTime.getHours() + "");
		preferenceTime.setHours(difference);
		
		difference = (closeTime.getHours()-timeStart.getHours());
		if( difference < 0) difference += 24;
		
		Log.i("time_close", closeTime.getHours() + "");
		closeTime.setHours(difference);

		Log.i("closeAfterPref", !(closeTime.before(preferenceTime)) + "");
		
		return !(closeTime.before(preferenceTime));
	}
	
	/*
	 *	Reset value of preferences in singleton SavedPreference 
	 */
	private void resetPreference() {
		SavedPreference.getInstance().resetContent();
	}
	
	/*
	 * Load value of preferences from singleton SavedPreference 
	 */
	private void loadPreference() {
		sHour.setSelection(SavedPreference.getInstance().getHour());
	    sMin.setSelection(SavedPreference.getInstance().getMin());
	    beerCheckBox.setChecked(SavedPreference.getInstance().getBeer());
	    danceCheckBox.setChecked(SavedPreference.getInstance().getDancefloor());
	    nosmokingCheckBox.setChecked(SavedPreference.getInstance().getNosmoking());
	    livemusicCheckBox.setChecked(SavedPreference.getInstance().getLivemusic());
	}
	
	/*
	 *	Save value of preferences and store in singleton SavedPreference 
	 */
	private void storePreference(){
		SavedPreference.getInstance().setHour(sHour.getSelectedItemPosition());
		SavedPreference.getInstance().setMin(sMin.getSelectedItemPosition());
	    SavedPreference.getInstance().setBeer(beerCheckBox.isChecked());
	    SavedPreference.getInstance().setDancefloor(danceCheckBox.isChecked());
	    SavedPreference.getInstance().setNosmoking(nosmokingCheckBox.isChecked());
	    SavedPreference.getInstance().setLivemusic(livemusicCheckBox.isChecked());
	}
	
}
	
